'''Train a simple deep CNN on the CIFAR10 small images dataset.
GPU run command:
    THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cifar10_cnn.py
It gets down to 0.65 test logloss in 25 epochs, and down to 0.55 after 50 epochs.
(it's still underfitting at that point, though).
Note: the data was pickled with Python 2, and some encoding issues might prevent you
from loading it in Python 3. You might have to load it in Python 2,
save it in a different format, load it in Python 3 and repickle it.
'''

from __future__ import print_function
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten, MaxoutDense, Highway
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD, Adadelta, Adagrad
from keras.utils import np_utils, generic_utils
from USPS_datapre.data_prepare import load_USPS_data
import matplotlib.pyplot as plt
from keras.layers.advanced_activations import PReLU
import numpy as np
import h5py

batch_size = 32
nb_classes = 10
nb_epoch = 20


img_rows, img_cols = 16, 16
img_channels = 1

print ('pseudo-label')
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = load_USPS_data()
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(img_channels, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3, border_mode='same',))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.35))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.35))

model.add(Flatten())
model.add(MaxoutDense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))

# let's train the model using SGD + momentum (how original).
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
model.load_weights('log/baseAug.hdf5')

testLo,testAc = model.evaluate(X_test,Y_test,show_accuracy=True)
pred = model.predict_classes(X_test)
print ('Test Accuracy: ' + str(testAc))
X_train = list(X_train)
X_test = list(X_test)
y_train = list(y_train)
for i in range(len(pred)):
    X_train.append(X_test[i])
    y_train.append(pred[i])
train_img_arrs = np.asarray(X_train,dtype='float32')
train_labels_arrs = np.asarray(y_train,dtype='int32')

trainVecPs_path = '/media/dell/cb552bf1-c649-4cca-8aca-3c24afca817b/dell/wxm/Data/Data-USPS/trainVecPs.h5'
f_train = h5py.File(trainVecPs_path,'w')
f_train.create_dataset('x',data=train_img_arrs)
f_train.create_dataset('y',data=train_labels_arrs)
f_train.close()